<?php

// **************************************************************
// | Name: 星空框架 任务处理
// **************************************************************
// | Version: V5.0
// **************************************************************
// | Author： xkyinzhe <zhonghuaxinxing@sina.cn>
// **************************************************************
// | City: 青岛
// **************************************************************
// | Time: 2021-09-18 09：15
// **************************************************************
declare(strict_types=1);

namespace app\common\services;

use app\common\model\SubOrder as SubOrderModel; // 订单模型
use app\common\model\GoodsOrder as GoodsOrderModel; // 产品订单模型
use app\common\model\Order as OrderModel;
use app\common\services\OrderServices; // 订单操作模型
use app\common\services\UserServices; // 用户服务模型
use app\common\services\SendMsg;
use app\common\services\Task;
use think\facade\Db;
use think\queue\Job;

/**
 * @xk 计划任务处理
 */
class Plan
{
    /**
     * @xk 计划任务分发
     *
     * @method   fire
     * @Version： V2.0
     * @Author   xkyinzhe
     * @Time     2020-11-10T10:26:47+080
     *
     * @param Job    $job  [description]
     * @param [type] $data [description]
     *
     * @return [type] [description]
     */
    public function fire(Job $job, $data)
    {
        $isJobStillNeedToBeDone = $this->checkDatabaseToSeeIfJobNeedToBeDone($data);
        if (!$isJobStillNeedToBeDone) {
            $job->delete();

            return;
        }
        $isJobDone = $this->doHelloJob($data); // 处理任务
        if ($isJobDone) {
            // 如果任务执行成功， 记得删除任务
            $job->delete();
            $content = json_encode($data)."----[处理成功]----SUCCESS\n";
            $path = 'task/plan_success/';
            createLog($path, $content);
        } else {
            $content = json_encode($data)."----[处理失败]----ERROR\n";
            $path = 'task/plan_error/';
            createLog($path, $content);
            if ($job->attempts() > 4) {
                $content = json_encode($data)."----[四次重新尝试未果，自动删除]----ERROR\n";
                $path = 'task/plan_success/';
                createLog($path, $content);
                $job->delete();
            }
        }
    }

    /**
     * 有些消息在到达消费者时,可能已经不再需要执行了.
     *
     * @param array|mixed $data 发布任务时自定义的数据
     *
     * @return bool 任务执行的结果
     */
    private function checkDatabaseToSeeIfJobNeedToBeDone($data)
    {
        return true;
    }

    /**
     * 根据消息中的数据进行实际的业务处理...
     */
    private function doHelloJob($data)
    {
        $jobAction = $data['jobAction'];
        $msgId = isset($data['msgId']) ? $data['msgId'] : '';
        $type = isset($data['type']) ? $data['type'] : '';
        $user_sn = isset($data['user_sn']) ? $data['user_sn'] : '';
        $l_user_sn = isset($data['l_user_sn']) ? $data['l_user_sn'] : '';
        $level = isset($data['level']) ? $data['level'] : '';
        $count = isset($data['count']) ? $data['count'] : '';
        $act = isset($data['act']) ? $data['act'] : '';
        $achievement_price = isset($data['achievement_price']) ? $data['achievement_price'] : 0;
        switch ($jobAction) {
            case 'orderCancel':
                self::orderCancel($msgId, $type); // 订单超时未付款自动取消
                break;
            case 'orderMakeSure':
                self::orderMakeSure($msgId, $type); // 订单超时后自动确认收货
                break;
            case 'syncBonusUser':
                self::syncBonusUser();
                break;
            case 'syncBonusBackMoney':
                self::syncBonusBackMoney();
                break;
            case 'syncAvgBackPushx':
                self::syncAvgBackPushx();
                break;
            case 'syncCheckUp':
                self::syncCheckUp($user_sn, $level);
                break;
            case 'syncUpdateCheckx':
                self::syncUpdateCheck();
                break;
            case 'syncUpdateCheck':

                break;
            case 'syncDoCheckUp':
                self::syncDoCheckUp($msgId, $l_user_sn, $level, $count);
                break;
            case 'createUser':
                self::createUser();
                break;
            case 'syncPayOverCheck':
                self::syncPayOverCheck($msgId, $l_user_sn, $level, $count);
                break;
            case 'syncBackMoney':
                self::syncBackMoney($msgId, $user_sn, $l_user_sn, $act);
                break;
            case 'syncSubOrderPay':
                self::syncSubOrderPay($msgId);
                break;
            case 'syncAgentBackMoney':
                self::syncAgentBackMoney($msgId, $user_sn, $l_user_sn, $achievement_price, $level);
                break;
            default:
                break;
        }
        $content = json_encode($data)."----[正在执行]----SUCCESS\n";
        $path = 'task/job/';
        createLog($path, $content);

        return true;
    }
    /**
     * @xk 订单超时自动取消
     *
     * @method orderCancel
     * @param  string      $sub_order_sn              [description]
     * @return [type]      [description]
     * @Time   2021-09-26
     * @City   青岛
     * @Author xkyinzhe    <zhonghuaxinxing@sina.cn>
     */
    public static function orderCancel($sub_order_sn = '')
    {
        $subOrderModel = new SubOrderModel();
        $goodsOrderModel = new GoodsOrderModel();
        $orderServices = new OrderServices();
        $orderModel = new OrderModel();
        Db::startTrans();
        $content = '';
        try {
            $param = request()->param();
            $condition = [];
            $condition[] = ['sub_order_sn', '=', $sub_order_sn];
            $order_info = $subOrderModel->where($condition)->field('`user_sn`,`status`,`order_sn`,`pay_status`,`pay_price`')->find();
            if (!$order_info) {
                throw new \think\Exception('订单不存在', 404);
            }
            if ($order_info['status'] != 0 || $order_info['pay_status'] != 0) {
                throw new \think\Exception("订单当前进入其他状态，不需要自动取消", 404);
            }
            $order_data = [];
            // 未付款 状态直接取消
          $order_data['status'] = 6; // 订单取消
          $order_data['cancel_time'] = date('Y-m-d H:i:s'); // 取消订单时间
          $res = $subOrderModel->where($condition)->save($order_data);
            // 检测是否已全部取消
            $count = $subOrderModel->where([['order_sn','=',$order_info['order_sn']]])->count();
            $has_count = $subOrderModel->where([['order_sn','=',$order_info['order_sn']],['status','=',6]])->count();
            if ($count == $has_count) {
                $order_res = $orderModel->where([['order_sn','=',$order_info['order_sn']]])->save($order_data);
            }
            $goods_order_res = $goodsOrderModel
                            ->where($condition)
                            ->save(['cancel_time'=>date('Y-m-d H:i:s'),'status'=>'6.1']);
            // 需要恢复 产品对应的库存
          $orderServices->syncStock($sub_order_sn, 'inc'); // 取消订单 需要退还原来的库存
          $content .="*********【".$sub_order_sn."】**订单取消成功********************************\n";
            Db::commit();
        } catch (\Exception $e) {
            $content .= $e->getMessage()."\n";
            Db::rollback();
        }
        $path = 'task/orderCancel/';
        createLog($path, $content);
        return true;
    }
    /**
     * @xk 异步执行 订单支付完成同步子订单状态
     * @param  string $order_sn [description]
     * @return [type]           [description]
     */
    public static function syncSubOrderPay($order_sn = '')
    {
        $orderServices = new OrderServices();
        $taskService = new Task();
        $content = '';
        Db::startTrans();
        try {
            $orderServices->syncSubOrderPay($order_sn);
            $content .="**********【".$order_sn."】**异步执行 订单支付完成 同步子订单状态*****************\n";
            Db::commit();
        } catch (\Exception $e) {
            $content .= $e->getMessage()."=======【".$order_sn."】===执行失败 自动重试=========\n";
            $msgDatax = ['time' => date('YmdHis'), 'msgId' => $order_sn,'jobAction' => 'syncSubOrderPay'];
            $delay = 5;
            $taskService->put($msgDatax, $delay);
            Db::rollback();
        }
        $path = 'task/syncSubOrderPay/';
        createLog($path, $content);
        return true;
    }
    /**
     * @xk 订单自动确认收货
     *
     * @method orderMakeSure
     * @param  [type]        $sub_order_sn              [description]
     * @return [type]        [description]
     * @Time   2021-10-09
     * @City   青岛
     * @Author xkyinzhe      <zhonghuaxinxing@sina.cn>
     */
    public static function orderMakeSure($sub_order_sn = '')
    {
        $subOrderModel = new SubOrderModel();
        $goodsOrderModel = new GoodsOrderModel();
        $orderServices = new OrderServices();
        $sendMsg = new SendMsg();
        $taskService = new Task();
        Db::startTrans();
        $content = '';
        try {
            if ('' == $sub_order_sn) {
                throw new \think\Exception('没有可以自动确认收货的订单', 404);
            }
            $condition = [];
            $condition[] = ['sub_order_sn', '=', $sub_order_sn];
            $order_info = $subOrderModel->where($condition)->field('`status`,`user_sn`,`is_buy`,`total_price`,`company_num`,`company_name`,`refund_status`')->find();
            if (!$order_info) {
                throw new \think\Exception('订单不存在', 404);
            }
            $user_sn = $order_info['user_sn'];

            // $first_count = $goodsOrderModel->where([['user_sn','=',$user_sn],['status','in','1.1,2.1'],['is_buy','=',0]])->count();
            // if ($first_count > 0 && $order_info['is_buy'] != 0) {
            //     throw new \think\Exception("存在未完成首购订单，自动延长收货周期", 301);
            // }
            if (2 != $order_info['status']) {
                throw new \think\Exception('订单当前状态，不允许执行收货', 404);
            }

            // 查看是否存在未处理的售后
            $refund_count = $goodsOrderModel->where($condition)->where([['status','in','5.1,5.11,5.2,5.21,5.23,5.24,5.3,5.31,5.33']])->count();
            if ($refund_count > 0) {
                throw new \think\Exception("当前订单存在未处理的售后，自动延长收货周期", 301);
            }
            if ($order_info['refund_status'] == 2) {
                throw new \think\Exception("订单进入整单售后，无需处理自动收货", 404);
            }
            // 执行订单核销
            $res = $subOrderModel
                  ->where($condition)
                  ->save(['status' => 3, 'receiving_time' => date('Y-m-d H:i:s')]);
            // 修改所有状态正常的商品
            $condition[] = ['status','in','2.1,5.12,5.22,5.32,5.34'];// 所有待收货或待核销商品订单 状态修改为已核销
            $order_goods_res = $goodsOrderModel
                              ->where($condition)
                              ->save(['status'=>'3.1','receiving_time'=>date('Y-m-d H:i:s')]);
            $orderServices->syncFinance($sub_order_sn); //  订单收货 或 核销 开始执行业绩结算
            $create_data = [];
            $create_data['sub_order_sn'] = $sub_order_sn;
            $create_data['total_price'] = $order_info['total_price'];
            $create_data['company_name'] = $order_info['company_name'];
            $create_data['company_num'] = $order_info['company_num'];
            $contentx = '尊敬的用户，您的订单编号为'.$sub_order_sn.'的订单已经通过系统自动确认收货成功！';
            $sendMsg->sendPushMsg($order_info['user_sn'], '签收通知', $contentx, 4, $create_data);
            $content .="***********【".$sub_order_sn."】*自动确认收货成功************************************\n";
            Db::commit();
        } catch (\Exception $e) {
            $content .= $e->getMessage()."【".$e->getCode()."】"."\n";
            if ($e->getCode() == 301) {
                // 如果是301 状态  需要延迟二分之一个确认收货周期
                $msgData = ['time' => date('YmdHis'), 'msgId' => $sub_order_sn, 'jobAction' => 'orderMakeSure'];
                $delay = config('web_config.shipping_hour')*12*3600;
                $taskService->put($msgData, $delay);
            }
            if ($e->getMessage() === 'SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction') {
                $msgData = ['time' => date('YmdHis'), 'msgId' => $sub_order_sn, 'jobAction' => 'orderMakeSure'];
                $delay = config('web_config.shipping_hour')*4*3600;
                $taskService->put($msgData, $delay);
            }
            Db::rollback();
        }
        $path = 'task/orderMakeSure/';
        createLog($path, $content);
        return true;
    }
    /**
     * @xk 定时统计参与分红人员
     *
     * @method syncBonusUser
     * @return [type]        [description]
     * @Time   2021-11-12
     * @City   青岛
     * @Author xkyinzhe      <zhonghuaxinxing@sina.cn>
     */
    public static function syncBonusUser()
    {
        $userServices = new UserServices();
        Db::startTrans();
        $content = '';
        try {
            $userServices->syncBonusUser();
            $content .="************参与分红人员统计成功*******************\n";
            Db::commit();
        } catch (\Exception $e) {
            $content .= $e->getMessage()."\n";
            Db::rollback();
        }
        $path = 'task/syncBonusUser/';
        createLog($path, $content);
        return true;
    }
    /**
     * @xk 执行异步佣金返利
     * @method          syncBackMoney
     * @param           [type] $order_sn  [description]
     * @param           [type] $user_sn  [description]
     * @param           [type] $l_user_sn  [description]
     * @param           [type] $act  [description]
     * @return          [type] [description]
     * @Version：V6.0
     * @Author：xkyinzhe <zhonghuaxinxing@sina.cn>
     * @City：青岛
     * @Time：2022-08-22
     */
    public static function syncBackMoney($sub_order_sn, $user_sn, $l_user_sn, $act)
    {
        $userServices = new UserServices();
        $taskService = new Task();
        Db::startTrans();
        $content = '';
        try {
            $userServices->syncAdvBackMoney($sub_order_sn, $user_sn, $l_user_sn, $act);
            $content .="****【".$sub_order_sn."】********执行佣金返利*******************\n";
            Db::commit();
        } catch (\Exception $e) {
            $content .= $e->getMessage()."\n";
            if (preg_match("/^SQLSTATE\[23000\]:*/", $e->getMessage())) {
                $msgDatax = ['time' => date('YmdHis'), 'msgId' => $sub_order_sn,'user_sn'=>$user_sn,'l_user_sn'=>$l_user_sn,'act'=>$act, 'jobAction' => 'syncBackMoney'];
                $delay = 60*5;
                $taskService->put($msgDatax, $delay);
                $content .="计划将于5分钟内重新执行\n";
            }
            Db::rollback();
        }
        $path = 'task/syncBackMoney/';
        createLog($path, $content);
        return true;
    }
    /**
     * @xk 定时执行分红
     *
     * @method syncBonusBackMoney
     * @return [type]             [description]
     * @Time   2021-11-12
     * @City   青岛
     * @Author xkyinzhe           <zhonghuaxinxing@sina.cn>
     */
    public static function syncBonusBackMoney()
    {
        $userServices = new UserServices();
        Db::startTrans();
        $content = '';
        try {
            $userServices->syncBonusBackMoney();
            $content .="************分红发放成功*******************\n";
            Db::commit();
        } catch (\Exception $e) {
            $content .= $e->getMessage()."\n";
            Db::rollback();
        }
        $path = 'task/syncBonusBackMoney/';
        createLog($path, $content);
        return true;
    }
    /**
     * @xk 执行计划用户升级 此方案暂时保留暂不采用
     * @method                                      syncCheckUp
     * @param                                       [type] $user_sn  [description]
     * @param                                       [type] $level  [description]
     * @return                                      [type] [description]
     * @Version：V5.0
     * @Author：xkyinzhe                             <zhonghuaxinxing@sina.cn>
     * @City：                                       青岛
     * @Time：2022-02-24Tfalse14:false32:false29+080
     */
    public static function syncCheckUp($user_sn)
    {
        $userServices = new UserServices();
        Db::startTrans();
        $content = '';
        try {
            $userServices->checkUpx($user_sn);
            $content .="**********".$user_sn."**升级检测成功*******************\n";
            Db::commit();
        } catch (\Exception $e) {
            $content .= $e->getMessage()."\n";
            Db::rollback();
        }
        $path = 'task/syncCheckUp/';
        createLog($path, $content);
        return true;
    }
    /**
     * @xk 执行同步升级数据
     * @method                                      syncDoCheckUp
     * @param                                       [type] $user_sn  [description]
     * @param                                       [type] $l_user_sn  [description]
     * @param                                       [type] $level  [description]
     * @return                                      [type] [description]
     * @Version：V5.0
     * @Author：xkyinzhe                             <zhonghuaxinxing@sina.cn>
     * @City：                                       青岛
     * @Time：2022-03-21Tfalse10:false46:false45+080
     */
    public static function syncDoCheckUp($user_sn, $l_user_sn, $level, $count)
    {
        $userServices = new UserServices();
        Db::startTrans();
        $content = '';
        try {
            $userServices->syncCheckUp($user_sn, $l_user_sn, $user_sn, $l_user_sn, $level, 'inc');
            $content .="************执行成功*******************\n";
            if ($count == 3000) {
                //  如果达到3000基数 则执行下一个循环
                self::syncUpdateCheck();
            }
            Db::commit();
        } catch (\Exception $e) {
            $content .= $e->getMessage()."\n";
            Db::rollback();
        }
        $path = 'task/syncDoCheckUp/';
        createLog($path, $content);
        return true;
    }
    /**
     * @xk 执行VIP 升级完成
     * @method          syncPayOverCheck
     * @param           [type] $user_sn  [description]
     * @param           [type] $l_user_sn  [description]
     * @param           [type] $level  [description]
     * @param           [type] $act  [description]
     * @return          [type] [description]
     * @Version：V5.0
     * @Author：xkyinzhe <zhonghuaxinxing@sina.cn>
     * @City：           青岛
     * @Time：2022-04-15
     */
    public static function syncPayOverCheck($user_sn, $l_user_sn, $level, $act)
    {
        $userServices = new UserServices();
        Db::startTrans();
        $content = '';
        try {
            $userServices->syncCheckUp($user_sn, $l_user_sn, $user_sn, $l_user_sn, $level, $act);
            $content .="*********【".$user_sn."】*【".$l_user_sn."】******【".$act."】******执行成功************\n";
            Db::commit();
        } catch (\Exception $e) {
            $content .= $e->getMessage()."\n";
            Db::rollback();
        }
        $path = 'task/syncPayOverCheck/';
        createLog($path, $content);
        return true;
    }
    /**
     * @xk 执行会员数据处理
     * @method                                      syncUpdateCheck
     * @return                                      [type] [description]
     * @Version：V5.0
     * @Author：xkyinzhe                             <zhonghuaxinxing@sina.cn>
     * @City：                                       青岛
     * @Time：2022-03-21Tfalse10:false46:false32+080
     */
    public static function syncUpdateCheck()
    {
        $userServices = new UserServices();
        // Db::startTrans();
        $content = '';
        // try {
        $userServices->syncUpdateCheck();
        $content .="************同步数据成功*******************\n";
        // Db::commit();
        // } catch (\Exception $e) {
        // $content .= $e->getMessage()."\n";
        // Db::rollback();
        // }
        $path = 'task/syncUpdateCheck/';
        createLog($path, $content);
        return true;
    }
    /**
     * @xk 异步执行 代理佣金发放
     * @method          syncAgentBackMoney
     * @param           [type] $sub_order_sn  [description]
     * @param           [type] $push_user_sn  [description]
     * @param           [type] $user_sn  [description]
     * @param           [type] $achievement_price  [description]
     * @param           [type] $user_level  [description]
     * @return          [type] [description]
     * @Version：V6.0
     * @Author：xkyinzhe <zhonghuaxinxing@sina.cn>
     * @City：青岛
     * @Time：2022-08-24
     */
    public static function syncAgentBackMoney($sub_order_sn, $push_user_sn, $user_sn, $achievement_price, $user_level)
    {
        $userServices = new UserServices();
        $taskService = new Task();
        Db::startTrans();
        $content = '';
        try {
            $userServices->syncAgentBackMoney($sub_order_sn, $push_user_sn, $user_sn, $achievement_price, $user_level, 0, 0, 0);
            $content .="********【".$sub_order_sn."】****代理佣金发放成功*******************\n";
            Db::commit();
        } catch (\Exception $e) {
            $content .= $e->getMessage()."=====【".$sub_order_sn."】=任务失败 自动重试========\n";
            // 任务失败 自动重新发布任务
            $msgData = ['time' => date('YmdHis'), 'msgId'=>$sub_order_sn, 'user_sn' => $push_user_sn,'l_user_sn'=>$user_sn,'achievement_price'=>$achievement_price,'level'=>$user_level,'jobAction' => 'syncAgentBackMoney'];
            $delay = 60;
            $taskService->put($msgData, $delay);
            Db::rollback();
        }
        $path = 'task/syncAgentBackMoney/';
        createLog($path, $content);
        return true;
    }
}
